// -*- C++ -*-
/*!
 * @file  LogRecTest.cpp
 * @brief 
 *
 */
#include <string.h>
#include <iostream>
#include <boost/bind.hpp>
#include "LogRecTest.h"

// Module specification
// <rtc-template block="module_spec">
static const char* logrectest_spec[] =
{
    "implementation_id", "LogRecTest",
    "type_name",         "LogRecTest",
    "description",       "LogRecTest component",
    "version",           "1.0",
    "vendor",            "leus, JSK",
    "category",          "vb_utility",
    "activity_type",     "LogRecTestComponent",
    "max_instance",      "10",
    "language",          "C++",
    "lang_type",         "compile",
    // Configuration variables
    "conf.default.componentconf_file",         "LogRecTest.conf",
    "conf.default.config", "LogRecTest0",    
    ""
};
// </rtc-template>
LogRecTest::LogRecTest(RTC::Manager* manager)
    : RTC::DataFlowComponentBase(manager)
      // <rtc-template block="initializer">
      // </rtc-template>
{
}

LogRecTest::~LogRecTest()
{
}

RTC::ReturnCode_t LogRecTest::onInitialize()
{
    // Registration: InPort/OutPort/Service
    // <rtc-template block="registration">
    // Set InPort buffers
    
    // Set OutPort buffer
  
    // Set service provider to Ports
        
    // Set service consumers to Ports
  
    // Set CORBA Service Ports

    // Bind variables and configuration variable
    bindParameter("componentconf_file", m_componentconf_file, "LogRecTest.conf");
    bindParameter("config", m_config, "LogRecTest0");

    tlog.set_instance_name(getInstanceName());
    
    // </rtc-template>    
    return RTC::RTC_OK;
}


/*
  RTC::ReturnCode_t LogRecTest::onFinalize()
  {
  return RTC::RTC_OK;
  }
*/

/*
  RTC::ReturnCode_t LogRecTest::onStartup(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/

/*
  RTC::ReturnCode_t LogRecTest::onShutdown(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/


RTC::ReturnCode_t LogRecTest::onActivated(RTC::UniqueId ec_id)
{
    // 設定ファイルの読み込み
    coil::Properties fprop;    
    std::ifstream compf(m_componentconf_file.c_str());
    if (compf.fail()) 
    {
        std::cerr << "failed to open component configuration file: "<< m_componentconf_file << std::endl;
        return RTC::RTC_ERROR;
    }
    fprop.load(compf);

    // ステート作成開始
    // 全部クリア
    m_stateServiceManager.clear();

    // 設定ファイルから自分に関係する部分を探す
    // なければエラー
    if (fprop.findNode(m_config)==0)
    {
        std::cerr << "faild to find config node" << std::endl;
        return RTC::RTC_ERROR;
    }
    
    coil::Properties prop;
    prop << fprop.getNode(m_config);
     
    std::vector<coil::Properties *> props;
        
    // stateの追加
    if (prop.findNode("state") !=0)
    {
        coil::Properties p;
        p << prop.getNode("state");
        
        std::cerr << std::setw(40) << std::setfill('=') << " " << std::endl;
        props = p.getLeaf();
        for(unsigned int i = 0; i < props.size(); i++)
        {
            try {
                StatePtr state = StateBase::create(*props[i]);
                m_stateServiceManager.addState(state);
                std::cerr << "state:" << state->name() << std::endl;                
            } catch(std::runtime_error &e) {
                std::cerr << e.what() << ":: ignored" << std::endl;
            }
        }
    }

    m_state_cnt = (short *)m_stateServiceManager.getState("cnt")->getPtr(0);

    std::cerr << std::setw(40) << std::setfill('=') << " " << std::endl;

    //make lisp class file for reading in euslisp
    std::vector<StatePtr> instates = m_stateServiceManager.getStates();
    tlog.make_lispclass(instates, m_config);

    m_state_cnt[0] = 0;
   
    // start log
    tlog.start_log();
    
    return RTC::RTC_OK;
}


RTC::ReturnCode_t LogRecTest::onDeactivated(RTC::UniqueId ec_id)
{
    // stop log
    tlog.stop_log();    

    return RTC::RTC_OK;
}


RTC::ReturnCode_t LogRecTest::onExecute(RTC::UniqueId ec_id)
{
    m_state_cnt[0]++;
    if(m_state_cnt[0] > 30000) m_state_cnt[0] =0;
    tlog.set_data(m_stateServiceManager.getStates());

    return RTC::RTC_OK;
}

/*
  RTC::ReturnCode_t LogRecTest::onAborting(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/

/*
  RTC::ReturnCode_t LogRecTest::onError(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/

/*
  RTC::ReturnCode_t LogRecTest::onReset(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/

/*
  RTC::ReturnCode_t LogRecTest::onStateUpdate(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/

/*
  RTC::ReturnCode_t LogRecTest::onRateChanged(RTC::UniqueId ec_id)
  {
  return RTC::RTC_OK;
  }
*/



extern "C"
{
 
    void LogRecTestInit(RTC::Manager* manager)
    {
        coil::Properties profile(logrectest_spec);
        manager->registerFactory(profile,
                                 RTC::Create<LogRecTest>,
                                 RTC::Delete<LogRecTest>);
    }
  
};
